package com.travelsky.app.security.support;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.Element;

import org.hibernate.FetchMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;

import com.travelsky.app.dao.base.IBaseDao;
import com.travelsky.app.persistence.Resource;
import com.travelsky.app.security.EhCacheBasedResourceCache;

public class EhCacheBasedResourceCacheSupport implements EhCacheBasedResourceCache {
    private static final String CACHE_KEY = "urlAuthorities";
    private Cache cache;
    private IBaseDao resourceDao;
    @Override
    public Map<String, String> getUrlAuthoritiesFromCache() {
        Element element = null;
        try {
            element = cache.get(CACHE_KEY);
        } catch (CacheException cacheException) {
            return null;
        }
        if (element == null) {
            return null;
        }
        return Collections.unmodifiableMap((Map<String, String>) element.getValue());
    }

    @Override
    public Map<String, String> putUrlAuthoritiesInCache() {
        DetachedCriteria resourceCriteria = DetachedCriteria.forClass(Resource.class);
        resourceCriteria.setFetchMode("roles", FetchMode.JOIN);
        resourceCriteria.add(Restrictions.eq("type", "URL"));
        List<Resource> urlResources = resourceDao.findByCriteria(resourceCriteria);
        Map<String, String> urlAuthorities = new HashMap<String, String>(urlResources.size());
        for (Resource resource : urlResources) {
            urlAuthorities.put(resource.getValue(), resource.getRoleAuthorities());
        }
        //放入缓存
        Element element = new Element(CACHE_KEY, urlAuthorities);
        cache.put(element);
        //返回不可修改的映射视图 安全
        return Collections.unmodifiableMap(urlAuthorities);
    }

    @Override
    public void refreshUrlAuthorities() {
        Map<String, String> urlAuthorities = getUrlAuthoritiesFromCache();
        if (urlAuthorities == null) {
            putUrlAuthoritiesInCache();
            return;
        }
        cache.remove(CACHE_KEY);
        putUrlAuthoritiesInCache();
    }

    public Cache getCache() {
        return cache;
    }

    public void setCache(Cache cache) {
        this.cache = cache;
    }

    public IBaseDao getResourceDao() {
        return resourceDao;
    }

    public void setResourceDao(IBaseDao resourceDao) {
        this.resourceDao = resourceDao;
    }
    
}
